#ifndef HSL_LOGGER_H
#define HSL_LOGGER_H

#include <string>
#include <sstream>
#include <ostream>
#include "hsl/Config.h"

/// This file defines a basic logging facility. See Boost.Logging for a more advanced logging framework.
namespace utility
{
    
    enum LogLevelEnum
    {
        DEBUG_LOG_LEVEL,
        INFO_LOG_LEVEL,
        WARN_LOG_LEVEL,
        ERROR_LOG_LEVEL,
        NOTICE_LOG_LEVEL,
        FATAL_LOG_LEVEL
    };
    
    /// Implements a simple logging facility.
    class Logger
    {
        std::ostringstream os_;
        static Logger* instance_;
        Logger();
    public:
        static Logger* getLogger();
        bool isDebugEnabled() const;
        void log(LogLevelEnum l, std::ostringstream& os, const char* filename, int lineno) const;
        std::ostringstream& getStream()
        {
            return os_;
        }
    };

}

#ifdef HSL_LOGGING_OFF
// do not print any logs
#define HSL_LOG_common(level, cptext)
#else
// print logs
#define HSL_LOG_common(level, cptext) do {\
utility::Logger::getLogger()->getStream() << cptext; \
utility::Logger::getLogger()->log(utility::level, utility::Logger::getLogger()->getStream(), __FILE__, __LINE__);  \
} while(0);
#endif //HSL_PERF_TEST

#define HSL_LOG_DEBUG(cptext)    HSL_LOG_common(DEBUG_LOG_LEVEL, cptext)
#define HSL_LOG_INFO(cptext)     HSL_LOG_common(INFO_LOG_LEVEL , cptext)
#define HSL_LOG_WARN(cptext)     HSL_LOG_common(WARN_LOG_LEVEL , cptext)
#define HSL_LOG_ERROR(cptext)    HSL_LOG_common(ERROR_LOG_LEVEL, cptext)
#define HSL_LOG_NOTICE(cptext)   HSL_LOG_common(NOTICE_LOG_LEVEL, cptext)
#define HSL_LOG_FATAL(cptext)    HSL_LOG_common(FATAL_LOG_LEVEL, cptext)

#endif